<template>
  <div class="level-layout">
    <TableSearchWidget ref="refSearch" :search="props.searchForm">
      <template v-slot:searchTail>
        <div style="display: flex; flex-direction: row">
          <el-button icon="search" plain round style="padding: 0 20px" @click="refreshData"/>
          <el-button
              round
              style="padding: 0 24px; margin-left: 16px"
              type="primary"
              :disabled="getFinishState"
              @click="onFinishSelect"
          >
            {{ props.finishLabel ? props.finishLabel : '完成' }}
          </el-button>
        </div>
      </template>
    </TableSearchWidget>

    <div style="display: flex; flex-direction: row; margin: 8px 16px 0 0; padding: 8px 0 0 0">
      <div class="level-nav" v-if="levelPath && levelPath.length > 1">
        <el-scrollbar>
          <div
              v-for="(item, index) in levelPath"
              :key="item.id"
              @click="onClickPath(index)"
              style="padding: 2px 0; display: flex; flex-direction: column; align-items: center"
          >
            <el-link
                v-if="index === levelPath.length - 1"
                style="font-size: 12px; background: white"
                disabled
            >
              {{ item.name }}
            </el-link>
            <template v-if="index < levelPath.length - 1">
              <el-link
                  style="font-size: 12px; background: white"
                  type="primary"
                  :underline="false"
                  @click="onClickPath(index)"
              >
                {{ item.name }}
              </el-link>
              <el-icon size="12">
                <ArrowDown/>
              </el-icon>
            </template>
          </div>
        </el-scrollbar>
      </div>
      <el-table
          class="level-table"
          style="flex: 1"
          :header-cell-style="{ background: '#FAFAFA', color: '#000', fontWeight: 'bold' }"
          :data="data"
          :border="tableBorder"
          :show-header="'MOVE' !== props.mode"
          sortable="custom"
          row-key="id"
          @row-click="getClickRow"
          default-expand-all
          v-loading="loading"
          @selection-change="selectionChangeHandle"
      >
        <el-table-column
            v-if="'MOVE' !== props.mode"
            type="selection"
            header-align="center"
            align="center"
            width="38"
            :selectable="onSelectable"
        />
        <template v-for="item in columns" :key="item.id">
          <el-table-column
              :prop="item.id"
              header-align="center"
              align="center"
              :key="item.id"
              :label="item.name"
              :column-key="item.id"
              v-if="!item.hide">
            <template #default="scope">
              <template v-if="'icon' === item.type">
                <div
                    @click="clickRightArrow(scope.row)" :style="[getRowStyle(scope.row)]"
                    style="
                    display: flex;
                    flex-direction: row;
                    justify-content: flex-end;
                    padding-right: 8px;
                  ">
                  <el-icon color="#409eff">
                    <ArrowRightBold/>
                  </el-icon>
                </div>
              </template>
              <template v-else>
                <div
                    :style="[getRowStyle(scope.row)]"
                    style="display: flex; flex-direction: row; justify-content: center"
                >
                  {{ scope.row[item.id] }}
                </div>
              </template>
            </template>
          </el-table-column>
        </template>
        <template #empty>
          <div style="padding-top: 32px; height: 150px">暂无数据</div>
        </template>
      </el-table>
    </div>
    <el-pagination
        class="level-table-pagination"
        :current-page="pagination.current || 1"
        :page-sizes="pagination.sizes || [10, 20, 50]"
        :default-page-size="pagination.pageSize || 10"
        :total="pagination.total || 0"
        layout="->, total, sizes, prev, pager, next"
        @size-change="sizeChangeHandle"
        @current-change="currentChangeHandle"
    />
  </div>
</template>

<script setup lang="ts">
import {computed, onActivated, onMounted, ref, toRaw} from 'vue'
import {runMethod} from '@/utils/DateUtil'
import TableSearchWidget from '@/widget/TableSearchWidget.vue'
import {ArrowDown, ArrowRightBold} from '@element-plus/icons-vue'

const current = ref()
const refSearch = ref()

const data = ref<Record<string, any>[]>([])
const loading = ref(false)
const searchParams = ref({})
const levelPath = ref([])

const props = withDefaults(
    defineProps<{
      load?: any
      columns: any
      mode?: string
      clickRow?: any
      levelMode?: boolean
      finishLabel?: string
      finishSelect?: any
      searchForm?: any
      rootItem: any
      pagination: any
      showBorder?: boolean
      selectChanged?: any
    }>(),
    {
      mode: 'MOVE',
      hasSelect: false,
      levelMode: true,
      columns: [],
      pagination: () => {
        return {
          current: 1,
          pageSize: 10,
          total: 0,
          sizes: [10, 20, 50]
        }
      }
    }
)

const selectItems = ref()
const columns = props.columns
const pagination = ref(props.pagination)
const tableBorder = ref(props.showBorder)

const emits = defineEmits(['currentChanged'])

const onSelectable = (row: any) => {
  return row.exist !== 1;
}

const handleRowClick = (row: any) => {
  current.value = toRaw(row);
  if (props.selectChanged) {
    props.selectChanged(current.value);
  }
}

const getClickRow = computed(() => {
  if ('MOVE' === props.mode) {
    return handleRowClick;
  } else if (props.levelMode) {
    return props.clickRow;
  } else {
    return undefined;
  }
})

const getRowStyle = (row: any) => {
  if ('MOVE' === props.mode) {
    if (row.id == current.value.id) {
      return {cursor: 'pointer', color: '#409eff'}
    } else {
      return {cursor: 'pointer'}
    }
  } else if (props.levelMode) {
    return {cursor: 'pointer'}
  } else {
    return {}
  }
}

const clickRightArrow = (row: any) => {
  if ('MOVE' === props.mode) {
    routeToItem(toRaw(row), true)
  }
}

const getFinishState = computed(() => {
  if ('MOVE' === props.mode) {
    return !current.value || !current.value.id
  } else {
    return !selectItems.value || selectItems.value.length === 0
  }
})

const onFinishSelect = () => {
  if (props.finishSelect) {
    if ('MOVE' === props.mode) {
      props.finishSelect(toRaw(current.value));
    } else {
      props.finishSelect(toRaw(selectItems.value));
    }
  }
}

const sizeChangeHandle = (size: any) => {
  pagination.value.pageSize = size
  loadData()
}

const currentChangeHandle = (pageNo: any) => {
  pagination.value.current = pageNo
  loadData()
}

const selectionChangeHandle = (val: any) => {
  selectItems.value = toRaw(val);
}

const loadData = async () => {
  if (props.load) {
    loading.value = true;

    const params: any = {
      current: pagination.value?.current,
      pageSize: pagination.value?.pageSize,
      ...searchParams.value,
      parentId: current.value.id || '',
    }

    await runMethod(params, async (runParams: any) => {
      const result = await props.load(runParams)

      if (result && result.code === 0 && result.data && result.data.data) {
        data.value = result.data.data
        pagination.value.total = result.data.total
      } else {
        data.value = [];
        pagination.value.total = 0;
      }
    })

    loading.value = false;
  }
}

const refreshData = async () => {
  searchParams.value = {
    ...refSearch.value?.getSearchParams(),
  }
  selectItems.value = []
  await loadData()
}

const updateCurrent = (item: any) => {
  current.value = {...item}
  emits('currentChanged', current.value)
}

const routeToItem = async (item: any, forceRoute: boolean=false) => {
  if (forceRoute || item.id !== current.value.id) {
    updateCurrent(item)
    levelPath.value.push({...item})
    await refreshData();
  }
}

const onClickPath = async (index: number) => {
  const count = levelPath.value.length
  const currItem = levelPath.value[index]

  if (currItem.id !== current.value.id) {
    levelPath.value.splice(index + 1, count - index - 1)
    updateCurrent(levelPath.value[index])
    await refreshData();
  }
}

const reloadData = () => {
  levelPath.value = []
  current.value = {...props.rootItem}
  levelPath.value.push({...props.rootItem})
  refreshData()
}

onMounted(() => {
  //reloadData()
})

onActivated(() => {

})

const getCurrent = () => {
  return current.value
}

defineExpose({
  getCurrent,
  reloadData,
  refreshData,
  routeToItem
})
</script>

<style scoped>
.level-layout {
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: flex-start;
}

.level-table-pagination {
  padding: 32px 8px 0;
  background: #fff;
}

.level-table {
  flex: 1;
}

.level-nav {
  width: 20%;
  margin-right: 16px;
  min-height: 200px;
}
</style>
